using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using Konst3d.Efficiency.Suite;

namespace Konst3d.Efficiency.Suite.SparsedBinary
{
    internal interface IStatisticStorage
    {
        int StartingYear
        {
            get;
        }

        IStatisticDay GetDay(DateTime date);
        IStatisticDay[] GetRange(DateTime begin, DateTime end);

        double GetSummaryValue(DateTime begin, DateTime end);
        double GetAverageValue(DateTime begin, DateTime end);

        void ForEach(StatisticDayCallback callback);
        void ForEach(DateTime begin, DateTime end, StatisticDayCallback callback);
    }

    internal class MonitoringStatistic: IMonitoringStatistic
    {
        #region IMonitoringStatistic Members

		public DateTime StartDate
		{
			get
			{
				return _created;
			}
		}

        public IStatisticDay Today
        {
            get
            {
                return _storage.GetDay(DateTime.Now);
            }
        }

        public IStatisticDay this[DateTime date]
        {
            get
            {
                return _storage.GetDay(date);
            }
        }

        public IEnumerable<IStatisticDay> GetRange(DateTime start, DateTime end)
        {
            return _storage.GetRange(start, end);
        }

        public double GetAverageValue()
        {
            return _storage.GetAverageValue(new DateTime(_storage.StartingYear, 1, 1), DateTime.Now);
        }

        public double GetAverageValue(DateTime start, DateTime end)
        {
            return _storage.GetAverageValue(start, end);
        }

        public double GetSummaryValue()
        {
            return _storage.GetSummaryValue(new DateTime(_storage.StartingYear, 1, 1), DateTime.Now);
        }

        public double GetSummaryValue(DateTime start, DateTime end)
        {
            return _storage.GetSummaryValue(start, end);
        }

        public int GetCommandmentViolationsCount()
        {
            return GetCommandmentViolationsCount(new DateTime(_storage.StartingYear, 1, 1), DateTime.Now);
        }

        public int GetCommandmentViolationsCount(DateTime start, DateTime end)
        {
            int count = 0;

            _storage.ForEach(start, end, (day) =>
            {
                if (day.Active && _activeDays.DaysOfWeek[(int)day.Date.DayOfWeek] && _activeDays.DaysOfMonth[day.Date.Day - 1])
                {
                    if (Comparer.Equals(day.Value, 0.0f))
                    {
                        ++count;
                    }
                }
            });

            return count;
        }

        #endregion

        #region Constructor

        public MonitoringStatistic(IStatisticStorage storage, MonitoringActiveDays activeDays, DateTime created)
        {
            Contract.Requires(storage != null);
            Contract.Requires(activeDays != null);

            _storage = storage;
            _activeDays = activeDays;
			_created = created;
        }

        #endregion // Constructor

        #region Fields

        private IStatisticStorage _storage;
        private MonitoringActiveDays _activeDays;
		private DateTime _created;

        #endregion // Fields
    }
}
